package com.hzw.saas.service.hpc.service;


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import com.hzw.saas.service.hpc.config.SshConfig;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import lombok.extern.slf4j.Slf4j;

/**
 * SSH连接器
 * 可以用SSH协议连接到指定地址并执行命令，获取返回结果
 *
 * @author yuli
 */
@Slf4j
public class SshHub {

    private SshConfig sshConfig;
    private List<String> stdout = new ArrayList<>();

    public SshHub() {
    }

    public SshHub(String host, int port, String username, String password) {
        this.sshConfig = new SshConfig();
        sshConfig.setHost(host);
        sshConfig.setPort(port);
        sshConfig.setUsername(username);
        sshConfig.setPassword(password);
    }

    public void setConfig(SshConfig sshConfig) {
        this.sshConfig = sshConfig;
    }

    public int execute(final String command) throws Exception {
        int returnCode = 0;
        JSch jsch = new JSch();

        Session session = null;
        Channel channel = null;
        try {
            // Create and connect session.
            session = jsch.getSession(sshConfig.getUsername(), sshConfig.getHost(), sshConfig.getPort());
            session.setPassword(sshConfig.getPassword());
            session.setConfig("StrictHostKeyChecking", "no");
            session.connect(5000);
            // Create and connect channel.
            channel = session.openChannel("exec");
            ((ChannelExec) channel).setCommand(command);
            channel.setInputStream(null);
            BufferedReader input = new BufferedReader(new InputStreamReader(channel
                .getInputStream()));
            channel.connect();
            log.info("The remote command is: " + command);

            // Get the output of remote command.
            String line;
            while ((line = input.readLine()) != null) {
                stdout.add(line);
            }
            input.close();
            // Get the return code only after the channel is closed.
            if (channel.isClosed()) {
                returnCode = channel.getExitStatus();
            }
        } finally {
            // Disconnect the channel and session.
            if (null != channel) {
                channel.disconnect();
            }
            if (null != session) {
                session.disconnect();
            }
        }
        return returnCode;
    }

    public void clear() {
        if (null != stdout) {
            stdout.clear();
        }
    }

    public List<String> getResult() {
        return stdout;
    }
}

